#!/usr/bin/python    
#+
#  HISTORY:
#    30/05/2012: GOX (MPE). First frozen version. 
#                           Header and footer of vectors not modified.
#     - 18/09/2012 : GOX (MPE) - SVN repository created on 
#				https://code.google.com/p/bcu
#                
#-
import numpy as np
import warnings
import subapDef_class as subap

class PixelWeight(object):
        '''
	AIM:
	    define the dsc_SubapPixelWeight vector (with weight==1 for each pixels)
	    provide some useful functions.

        FUNCTIONS:
	   - excludeSubap
	   - pixelWeightCrop
	   - pixelWeightCropAll

	REQUIRES:
	   subapDef object (instance of subapDef_class)
	   
        '''
        def __init__(self, subapDef):
            self.nsubap_dsp0=int(np.size(subapDef.vectorsBCU[0])/64 )
            self.nsubap_dsp1=int(np.size(subapDef.vectorsBCU[1])/64)
	    
	    self.nsubap=[self.nsubap_dsp0,self.nsubap_dsp1]

	    self.subapDef_object=subapDef
	    self.subapDEF=subapDef.vectorsBCU
	    self._arrayIndices=subapDef._arrayIndices()
            self.vectorsBCU  = self.setDefaultVectorsBCU()
	    self.arrayHuman  = self.setArray()

        def setDefaultVectorsBCU(self):
            vectorsBCU=[np.ones(np.size(self.subapDEF[0])),np.ones(np.size(self.subapDEF[1]))]
            return vectorsBCU

        def setArray(self):
	    return self._pixelWeight2array()

        def setDefault(self):
            self.vectorsBCU = self.setDefaultVectorsBCU()
	    self.arrayHuman = self.setArray()

        def getVectorsBCU(self):
            return self.vectorsBCU

        def getVectorDSP0(self):
            return self.vectorsBCU[0]

        def getVectorDSP1(self):
            return self.vectorsBCU[1]

        def excludeSubap(self, subap_nb, dsp_nb):
            '''
	     excludes subaperture(s) with # [subap_nb], of dsp_nb (0 for left, 1 for right).
	     the subapertures numbering can be visualized using subap.show() 
	     (subap being an instance of subapDef_class).

	     'excludes' here means setting the pixel weight of 
	     every pixel within the subap to 0.
	     So the return slope will be 0.
	    '''
	    ## N.B. Header and Footer (resp. for 2 first and the last subapertures) 
            ##      of pixelWeight are not nulled here.
	    ##      do not diminish the capabilities.

            #print "numbers of real subapertures:", np.size(self.vectorsBCU[dsp_nb])/64-3
	    for i in range(0,np.size(subap_nb)):
		ds=np.mod(subap_nb[i],2)
		self.vectorsBCU[dsp_nb]\
		    [(subap_nb[i]-ds+2)*64+ds:ds+128+(subap_nb[i]-ds+2)*64:2]=0		    

	    self.arrayHuman=self.setArray()

	def pixelWeightCropAll(self, crop=[1,1,1,1]):
	    '''
	    windowing/cropping of ALL the subapertures (both pnCCD sides/DSPs)
	    crop=[left,right,top,bottom] in pixel
	    maximum values are '4'. (==nulling)
	    '''
            
            # Creating crop array
	    weight_array=np.ones((8,8))
	    xdimen=np.size(weight_array,0)
	    ydimen=np.size(weight_array,1)
	
	    weight_array[0:crop[0],               ]=0
	    weight_array[(xdimen-crop[1]):xdimen, ]=0
	    weight_array[:,0:crop[2]              ]=0
	    weight_array[:,(ydimen-crop[3]):ydimen]=0
	    weight=weight_array.flatten()

	    for i in range(0, self.nsubap[0]-2):
	    	    self._pixelWeightCrop([i],0,weight)
	    for i in range(0, self.nsubap[1]-2):
	     	    self._pixelWeightCrop([i],1,weight)
	    self.arrayHuman=self.setArray()	    

	def pixelWeightCrop(self,subap_nb,dsp_nb, weight):
	    '''
	    windowing/cropping of subaperture(s) [subap_nb] of dsp dsp_nb

	    crop=[left,right,top,bottom] in pixel
	    maximum values are '4'. (==nulling)
	    '''

	    self._pixelWeightCrop(subap_nb,dsp_nb,weight)
	    self.arrayHuman=self.setArray()

	def _pixelWeightCrop(self,subap_nb,dsp_nb, weight):
	    '''
	     CROP subap #x
	     left, right, bottom, top: define the number of pixel
	     to 'crop' from the initally defined pixelWeight sub-ap.
	     e.g. if [l,r,b,t]=[1,1,1,1], and 'weight_array' is a 
	     ones((8,8)), the sub-ap size is effectively 7x7
	     dim=[left,right,bottom,top]
	    '''
	    for i in range(0,np.size(subap_nb)):
		 ds=np.mod(subap_nb[i],2)
		 self.vectorsBCU[dsp_nb]\
			[ds+(subap_nb[i]-ds+2)*64:ds+128+(subap_nb[i]-ds+2)*64:2] *=weight

		 if (subap_nb[i] == 0) | (subap_nb[i] == 1) :
			    self.vectorsBCU[dsp_nb]\
				[ds+(subap_nb[i]-ds)*64:ds+128+(subap_nb[i]-ds)*64:2] *=weight
		    

	def _pixelWeight2array(self):
            '''
	    transforms dsc_SubapPixelWeight vector into a 2D array for visualization.
	    
	    GOX 22/03/2012 - corrected
	    '''
            ## N.B. Header and Footer (resp. for 2 first and the last subapertures) 
            ##      of pixelWeight are not nulled here.
	    ##      do not diminish the capabilities.

	    subap_pixel_weight=[np.array(self.subapDEF[0],float),np.array(self.subapDEF[1],float)]

	    # ** DSP0 ***
	    for i in range(0, self.nsubap[0],2):
                subap_pixel_weight[0][i*64:128+i*64:2]=self.vectorsBCU[0]\
			[i*64:128+i*64:2]

	    for i in range(0, self.nsubap[0],2):
                subap_pixel_weight[0][i*64+1:1+128+i*64:2]=self.vectorsBCU[0]\
	    		[1+i*64:1+128+i*64:2]
	    # ** DSP1 ***
	    for i in range(0, self.nsubap[1],2):
                subap_pixel_weight[1][i*64:128+i*64:2]=self.vectorsBCU[1]\
			[i*64:128+i*64:2]

	    for i in range(0, self.nsubap[1],2):
                subap_pixel_weight[1][i*64+1:1+128+i*64:2]=self.vectorsBCU[1]\
	    		[1+i*64:1+128+i*64:2]

	    array=self.subapDef_object._subap_pix_ptr2array(self.subapDEF[0],\
								    self.subapDEF[1],\
								    subap_pixel_weight)
	    return array



if __name__ == "__main__":
    subap=subap.SubapDef()
    subap.shiftSHPupils([5,0],[5,0],[-5,0])
    pixelWeight=PixelWeight(subap)
    print "OK"
